#pragma once

#include <functional>
#include <vector>
#include <atomic>
#include <memory>
#include <mutex>

#include "noncopyable.h"
#include "Timestamp.h"
#include "CurrentThread.h"

class Channel;
class Poller;
// 事件循环类 主要包含两个大类 Channel Poller(epoll的抽象)
class EventLoop
{
public:
    using Functor = std::function<void()>;

    EventLoop();
    ~EventLoop();

    // 开启事件循环
    void loop();
    // 退出事件循环
    void quit();

    Timestamp pollReturnTime() const {return pollReturnTime_;}

    // 在当前loop中执行回调
    void runInLoop(Functor cb);
    // 把回调放入队列中 唤醒loop所在线程 执行回调
    void queueInLoop(Functor cb);
    // 唤醒loop所在线程
    void wakeup();

    // EventLoop的方法 -> Poller的方法
    void updateChannel(Channel* channel);
    void removeChannel(Channel* channel);
    bool hasChannel(Channel* channel);

    // 判断EventLoop对象是否在自己的线程里面
    bool isInLoopThread() const {return threadId_ == CurrentThread::tid();}

    int createEventfd();


private:
    using ChannelList = std::vector<Channel*>;

    void handleRead(); // wakeup
    void doPendingFunctors(); // 执行回调


    std::atomic_bool looping_;
    std::atomic_bool quit_; // 标致推出loop循环
    
    const pid_t threadId_; // 记录当前loop所在线程id
    Timestamp pollReturnTime_; // 记录poller返回发生事件的channels的时间点
    std::unique_ptr<Poller> poller_;

    int wakeupFd_; // 当mainLoop获取一个新用户的channel 通过轮询算法选择一个subloop 通过该成员 唤醒subloop 处理channel
    std::unique_ptr<Channel> wakeupChannel_;

    ChannelList activeChannels_;
  

    std::atomic_bool callingPendingFunctors_; // 标识当前loop是否有需要执行的回调操作
    std::vector<Functor> pendingFuntors_; // 存储loop需要执行的所有回调操作
    std::mutex mutex_; // 用于保护上面vector容器的线程安全操作



};